﻿using Config;
using GameData.Common;
using GameData.Domains;
using GameData.Domains.Character;
using GameData.Domains.Character.AvatarSystem;
using GameData.Domains.Extra;
using GameData.Domains.Information;
using GameData.Domains.Taiwu;
using GameData.Serializer;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using TaiwuModdingLib.Core.Plugin;

namespace TransferTaiwuModDotNetCore
{
    [PluginConfig("TransferTaiwuMod", "艾尔", "1.0.0")]
    public class TransferTaiwu : TaiwuRemakePlugin
    {
        private Harmony harmony;
        /**保留相貌 性转  _transgender*/
        private static bool inheritAvator;
        /**保留姓名*/
        private static bool overwriteName;
        /**保留特性*/
        private static int inheritTX;
        /**合并天赋保留最大值*/
        private static bool inheritTF;
        //保留七元  _personalities
        private static bool inheritPersonalities;
        //保留性格  _baseMorality
        private static bool inheritMorality;
        //吸收合并6维
        private static int mergeMainAttributes;


        public override void Dispose()
        {
            if (harmony != null)
            {
                harmony.UnpatchSelf();
            }
        }

        public override void Initialize()
        {
            harmony = Harmony.CreateAndPatchAll(typeof(TransferTaiwu));
        }

        public override void OnModSettingUpdate()
        {
            DomainManager.Mod.GetSetting(this.ModIdStr, "inheritAvator", ref inheritAvator);
            DomainManager.Mod.GetSetting(this.ModIdStr, "inheritTX", ref inheritTX);
            DomainManager.Mod.GetSetting(this.ModIdStr, "inheritTF", ref inheritTF);
            DomainManager.Mod.GetSetting(this.ModIdStr, "inheritPersonalities", ref inheritPersonalities);
            DomainManager.Mod.GetSetting(this.ModIdStr, "inheritMorality", ref inheritMorality);
            DomainManager.Mod.GetSetting(this.ModIdStr, "mergeMainAttributes", ref mergeMainAttributes);
            DomainManager.Mod.GetSetting(this.ModIdStr, "overwriteName", ref overwriteName);
        }

        [HarmonyPrefix, HarmonyPatch(typeof(ExtraDomain), "GetCharacterSecretInformationUsedCount")]
        public static bool PreGetSecretInformationUsedCount(ExtraDomain __instance, ref sbyte __result,
            int characterId, int metaDataId)
        {
            SecretInformationCharacterUsedCount usedCountData;
            __instance.TryGetElement_CharacterSecretInformationUsedCounts(characterId, out usedCountData);
            if(usedCountData == null)
            {
                Dictionary<int, SecretInformationCharacterUsedCount> dic = Traverse.Create(__instance)
                    .Field("_characterSecretInformationUsedCounts")
                    .GetValue<Dictionary<int, SecretInformationCharacterUsedCount>>();
                dic.Remove(characterId);
                __result = 0;
                return false;
            }
            return true;
        }

        [HarmonyPrefix, HarmonyPatch(typeof(ExtraDomain), "ClearCharacterSecretInformationUsedCount")]
        public static bool PreClearCharacterSecretInformationUsedCount(ExtraDomain __instance,
            int characterId, int metaDataId)
        {
            SecretInformationCharacterUsedCount usedCountData;
            __instance.TryGetElement_CharacterSecretInformationUsedCounts(characterId, out usedCountData);
            if (usedCountData == null)
            {
                Dictionary<int, SecretInformationCharacterUsedCount> dic = Traverse.Create(__instance)
                    .Field("_characterSecretInformationUsedCounts")
                    .GetValue<Dictionary<int, SecretInformationCharacterUsedCount>>();
                dic.Remove(characterId);
                return false;
            }
            return true;
        }

        [HarmonyPostfix, HarmonyPatch(typeof(TaiwuDomain), "TransferTaiwuData", new Type[] { typeof(DataContext),
            typeof(GameData.Domains.Character.Character), typeof(GameData.Domains.Character.Character), typeof(bool) })]
        public static void PostTransferTaiwuData(TaiwuDomain __instance, DataContext context,
            GameData.Domains.Character.Character newTaiwuChar, GameData.Domains.Character.Character oldTaiwuChar, bool randomSuccessor)
        {
            AvatarData oldAvatarData = oldTaiwuChar.GetAvatar();
            AvatarData newAvatarData = newTaiwuChar.GetAvatar();
            if (inheritAvator)
            {
                Traverse traverse = Traverse.Create(newTaiwuChar);
                newTaiwuChar.SetAvatar(Serializer.CreateCopy<AvatarData>(oldAvatarData), context);
                if (oldAvatarData.GetGender() == newTaiwuChar.GetGender())
                {
                    traverse.Field("_transgender").SetValue(false);
                }
                else
                {
                    traverse.Field("_transgender").SetValue(true);
                }
            }
            if (overwriteName)
            {
                FullName fullName = Serializer.CreateCopy < FullName > (oldTaiwuChar.GetFullName());
                newTaiwuChar.SetFullName(fullName,context);
            }
            if (inheritTF)
            {
                unsafe
                {
                    var x = oldTaiwuChar.GetBaseLifeSkillQualifications();
                    var y = newTaiwuChar.GetBaseLifeSkillQualifications();
                    for (int i = 0; i < 16; i++)
                    {
                        *(x.Items + i) = Math.Max(*(x.Items + i), *(y.Items + i));
                    }
                    newTaiwuChar.SetBaseLifeSkillQualifications(ref x, context);


                    var a = oldTaiwuChar.GetBaseCombatSkillQualifications();
                    var b = newTaiwuChar.GetBaseCombatSkillQualifications();
                    for (int i = 0; i < 14; i++)
                    {
                        *(a.Items + i) = Math.Max(*(a.Items + i), *(b.Items + i));
                    }
                    newTaiwuChar.SetBaseCombatSkillQualifications(ref a, context);
                }
                
            }
            if (inheritTX > 0)
            {
                switch (inheritTX)
                {
                    case 1:
                        newTaiwuChar.SetFeatureIds(oldTaiwuChar.GetFeatureIds(), context);
                        break;
                    case 2:
                        foreach (var feature in oldTaiwuChar.GetFeatureIds())
                        {
                            if (CharacterFeature.Instance[feature].GeneticProb > 0)
                            {
                                newTaiwuChar.AddFeature(context, feature, true);
                            }
                        }
                        break;
                    case 3:
                        List<short> newList = newTaiwuChar.GetFeatureIds();

                        Dictionary<short, short> dic = new Dictionary<short, short>();

                        List<CharacterFeatureItem> newTuple = new List<CharacterFeatureItem>();
                        foreach (var feature in newTaiwuChar.GetFeatureIds())
                        {
                            newTuple.Add(CharacterFeature.Instance[feature]);
                        }

                        foreach (var feature in oldTaiwuChar.GetFeatureIds())
                        {
                            var featureItem = CharacterFeature.Instance[feature];
                            bool need = featureItem.GeneticProb > 0;
                            if (newTuple.Count > 0)
                            {
                                foreach (CharacterFeatureItem valueTuple in newTuple)
                                {
                                    if (featureItem.MutexGroupId == valueTuple.MutexGroupId 
                                        && featureItem.Level <= valueTuple.Level)
                                    {
                                        need = false;
                                        break;
                                    }
                                }
                            }
                            if (need)
                            {
                                newTaiwuChar.AddFeature(context, feature, true);
                            }
                        }

                        break;
                }
                
            }
            if (inheritPersonalities)
            {
                Personalities old = oldTaiwuChar.GetPersonalities();
                Traverse.Create(newTaiwuChar).Field("_personalities").SetValue(Serializer.CreateCopy<Personalities>(old));
            }
            if (inheritMorality)
            {
                newTaiwuChar.SetBaseMorality(oldTaiwuChar.GetBaseMorality(), context);
            }
            /**
            if (mergeMainAttributes > 0)
            {
                MainAttributes oldMainAttributes = oldTaiwuChar.GetBaseMainAttributes();
                MainAttributes newMainAttributes = newTaiwuChar.GetBaseMainAttributes();
                unsafe
                {
                    for (int i = 0; i < 6; i++)
                    {
                        short a = oldMainAttributes.Items[i];
                        newMainAttributes.Items[i] = (short)(newMainAttributes.Items[i] * mergeMainAttributes / 100 + a);
                    }
                }

            }*/
        }
    }
}